


import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

import java.lang.reflect.*;

public class Listener4 extends JFrame {

   public Listener4() {
      JButton open = new JButton("Open");
      JButton close = new JButton("Close");
      JButton save = new JButton("Save");
      getContentPane().setLayout(new FlowLayout());
      getContentPane().add(open);
      getContentPane().add(close);
      getContentPane().add(save);

      open.addActionListener((ActionListener)DynamicProxy.makeProxy(this, "open", ActionListener.class));
      close.addActionListener((ActionListener)DynamicProxy.makeProxy(this, "close", ActionListener.class));
      save.addActionListener((ActionListener)DynamicProxy.makeProxy(this, "save", ActionListener.class));

      pack();
      setVisible(true);
   }

   public void open() {
      System.out.println("Open a file");
   }
   public void close() {
      System.out.println("Close a file");
   }
   public void save() {
      System.out.println("Save a file");
   }




   public static void main(String[] args) {
      new Listener4();
   }

}


class DynamicProxy implements InvocationHandler {

   Object target;
   String methodName;
   public static Object makeProxy(Object target, 
                                  String methodName, 
                                  Class impl) {
      ClassLoader loader = target.getClass().getClassLoader();
      DynamicProxy handler = new DynamicProxy();
      handler.target = target;
      handler.methodName = methodName;
      
      return Proxy.newProxyInstance(loader ,
                                    new Class[]{impl},
                                    handler);
   }

   public Object invoke(Object proxy, Method method, Object[] args) {
      try {
         Object[] noArgs = {};
         Class[] argTypes = {};         
         Method targetMethod = target.getClass().getMethod(methodName, argTypes);        
         return targetMethod.invoke(target, noArgs); 
      } catch (Exception e ) {
         e.printStackTrace();
         return null;
      }
   }
}
